package controllers

import (
	"demo_system/common"
	"demo_system/core"
	"demo_system/datamodels"
	"demo_system/encrypt"
	"demo_system/lib/cookie"
	"demo_system/lib/validation"
	"demo_system/services"
	"encoding/json"
	"fmt"
	"github.com/kataras/iris"
	"github.com/kataras/iris/mvc"
	"strconv"
	"strings"
	"time"
)

type UserController struct {
	Ctx      iris.Context
	UserServ services.IUserService
	MyVlaid  validation.ICustomValidator
}

func (uc *UserController) GetRegister() mvc.View {
	return mvc.View{
		Name: "user/register.html",
	}
}

//用户注册
func (uc *UserController) PostRegister() mvc.View {
	phoneNum := uc.Ctx.FormValue("phoneNum")
	user := &datamodels.User{}
	iPhoneNum := []byte(phoneNum)
	first, _ := strconv.ParseInt(string(iPhoneNum[0:8]), 10, 32)
	last, _ := strconv.ParseInt(string(iPhoneNum[8:11]), 10, 32)

	randId := common.PseudoEncrypt8(int32(first), int32(last))
	user.UserName = fmt.Sprintf("user%d", randId)

	//新建form tag解析器
	dec := common.NewDecoder(&common.DecoderOptions{TagName: "form"})
	//根据tag标签将form表单中的值映射到结构体实例中
	if err := dec.Decode(uc.Ctx.Request().Form, user); err != nil {
		uc.Ctx.Application().Logger().Debug("映射结构体失败: ", err)
		return common.Warn("获取用户信息失败#2", "")
	}

	//对结构体中的数据进行验证
	sliceErr := uc.MyVlaid.Validate(user)
	sErr := strings.Join(sliceErr, " , ")
	if len(sliceErr) != 0 {
		uc.Ctx.Application().Logger().Debug("验证失败: ", sErr)
		return common.Warn(sErr, "")
	}
	_, err := uc.UserServ.AddUser(user)
	if err != nil {
		uc.Ctx.Application().Logger().Debug("新增用户失败: ", err)
		return common.Warn("新增用户失败", "")
	}
	uc.Ctx.Application().Logger().Debug("新增用户成功")
	return common.Warn("新增用户成功", "/user/login")
}

//用户登录展示页
func (uc *UserController) GetLogin() mvc.View {
	return mvc.View{
		Name: "user/login.html",
	}
}

func (uc *UserController) PostLogin() mvc.Result {
	var (
		phoneNum = uc.Ctx.FormValue("phoneNum")
		password = uc.Ctx.FormValue("passWord")
	)
	oUser, isOk := uc.UserServ.IsPwdSuccess(phoneNum, password)
	if !isOk {
		return mvc.View{
			Name: "shared/response.html",
			Data: iris.Map{
				"warn": "用户名或密码错误",
				"go":   "/user/login",
			},
		}
	}
	now := time.Now().UnixNano() / 1e6
	//设置用户id到cookie
	joinStr, err := json.Marshal(core.LoginStatus{oUser.ID, now})
	if err != nil {
		uc.Ctx.Application().Logger().Error("用户登录信息json化失败: ", err)
		return common.Warn("登录发生错误#1", "/user/login")
	}
	encryptStr, err := encrypt.EnPwdCode([]byte(joinStr))
	if err != nil {
		uc.Ctx.Application().Logger().Error("加密uid失败: ", err)
		return common.Warn("登录失败, 请重试!!", "/user/login")
	}

	sId := strconv.FormatInt(oUser.ID, 10)

	//设置cookie
	cookie.GlobalCookie(uc.Ctx, "uid", sId)
	cookie.GlobalCookie(uc.Ctx, "sign", encryptStr)

	//跳转到编辑页面
	return mvc.Response{
		Path: "/user/edit",
	}
}

func (uc *UserController) GetEdit() mvc.View {
	uid := uc.Ctx.GetCookie("uid")
	uModel, err := uc.UserServ.GetUserInfoById(uid)
	if err != nil {
		return common.Warn("获取用户信息失败", "")
	}
	return mvc.View{
		Name: "user/edit.html",
		Data: iris.Map{
			"ID": uModel.ID,
		},
	}
}

//用户注册
func (uc *UserController) PostEdit() mvc.View {
	user := &datamodels.User{}
	user.ID, _ = strconv.ParseInt(uc.Ctx.FormValue("id"), 10, 32)
	user.PhoneNum = uc.Ctx.FormValue("phoneNum")
	//对结构体中的数据进行验证
	sliceErr := uc.MyVlaid.Validate(user)
	sErr := strings.Join(sliceErr, " , ")
	if len(sliceErr) != 0 {
		uc.Ctx.Application().Logger().Debug("验证失败: ", sErr)
		return common.Warn(sErr, "")
	}
	_, err := uc.UserServ.ChangeUserPhone(user)
	if err != nil {
		uc.Ctx.Application().Logger().Debug("修改用户手机号失败: ", err)
		return common.Warn("修改用户手机号失败", "")
	}
	uc.Ctx.Application().Logger().Debug("修改用户手机号成功")
	return common.Warn("修改用户手机号成功", "/user/edit")

}
